﻿// ------------------------------------------------------------------------
// 版权信息
// 版权归重庆虫儿飞科技有限公司所有。
// 所有权利保留。
// 官方网站：https://netokit.com
// 许可证信息
// Neto.Kit 项目主要遵循 MIT 许可证和 Apache 许可证（版本 2.0）进行分发和使用。
// 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。
// 
// 使用条款
// 使用本代码应遵守相关法律法规和许可证的要求。
// 
// 免责声明
// 对于因使用本代码而产生的任何直接、间接、偶然、特殊或后果性损害，我们不承担任何责任。
// 
// 其他重要信息
// Neto.Kit 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。
// 有关 Neto.Kit 项目的其他详细信息，请参阅位于源代码树根目录中的 COPYRIGHT 和 DISCLAIMER 文件。
// 
// 更多信息
// 请访问 https://netokit.com 获取更多关于 Neto.Kit 项目的许可证和版权信息。
// ------------------------------------------------------------------------

using Neto.Db.SqlSugar;
using Neto.Db.SqlSugar.Paged;

namespace Neto.Application.Api;

/// <summary>
///     系统日志
/// </summary>
[Authorize] //jwt授权
[ApiDescriptionSettings("Api", Name = "SysLog")]
//[MaApi(controller: "SysLog", controllerDescription: "系统日志", PCode = "Api")]
[ApiArea()]
[PgApiController("系统日志服务", "LogManage")]
[PgApiMenu("系统日志", "log-manage_sys-log", "LogManage", Icon = "fluent:notepad-28-regular", Sort = 3)]
//[Route("Api/[controller]/[action]")]
public class ApiSysLogService(ISqlSugarClient db)
    : IDynamicApiController
{
    /// <summary>
    ///     新增一条
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [PgApiAction("新增一条")]
    [OperationId(nameof(Insert))]
    public async Task<long> Insert(ApiSysLogInput input)
    {
        ////验证 父级下 唯一 Key是否存在
        //var isexit = await db.Queryable<SysLog>().AnyAsync(o => o.PKey == input.PKey && o.Key == input.Key);
        //if (isexit)
        //{
        //    throw Oops.Bah("唯一标识Key不能重复");
        //}
        var addentity = input.Adapt<SysLog>();
        return await db.InsertRsIdAsync(addentity);
    }

    /// <summary>
    ///     更新一条
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [PgApiAction("更新一条")]
    [OperationId(nameof(Update))]
    [HttpPut]
    public async Task<bool> Update(ApiSysLogInput input)
    {
        ////验证 父级下 唯一 Key是否存在
        //var isexit = await db.Queryable<SysLog>().AnyAsync(o => o.PKey == input.PKey && o.Key == input.Key && o.Id != input.Id);
        //if (isexit)
        //{
        //    throw Oops.Bah("唯一标识Key不能重复");
        //}
        var dbentity = await db.Queryable<SysLog>().With(SqlWith.Null).FirstAsync(o => o.Id == input.Id.Value);
        input.Adapt(dbentity);
        return await db.UpdateAsync(dbentity);
    }

    /// <summary>
    ///     删除一条
    /// </summary>
    /// <param name="id"></param>
    [PgApiAction("删除一条")]
    [OperationId(nameof(Delete))]
    public async Task<bool> Delete(long id)
    {
        //if (id <= 0) throw Oops.Bah("id不能为0");
        //return  await db.DeleteByIdAsync<SysLog>(id);
        return await db.FakeDeleteAsync<SysLog>($"{id}");
    }

    /// <summary>
    ///     批量删除
    /// </summary>
    /// <param name="ids">需要删除的数据，多条以英文逗号隔开</param>
    [PgApiAction("批量删除")]
    [OperationId(nameof(BatchDelete))]
    public async Task<bool> BatchDelete(string ids)
    {
        //return await db.DeleteByIdsAsync<SysLog>(ids);
        return await db.FakeDeleteAsync<SysLog>(ids);
    }

    /// <summary>
    ///     查询一条
    /// </summary>
    /// <param name="id"></param>
    [PgApiAction("查询一条")]
    [HttpPost]
    [OperationId(nameof(Get))]
    public async Task<ApiSysLogOut> Get(long id)
    {
        /* 多表关联的一个写法，当然也可以用导航写法
         var query5 = await db.Queryable<SysLog>()
           //.LeftJoin<Custom>   ((o, cus ) => o.CustomId == cus.Id)//多个条件用&&
           //.LeftJoin<OrderDetail> ((o, cus, oritem) => o.Id == oritem.OrderId)
           .Where(o => o.Id == id)
           .Select((o) => new ApiSysLogOut {
                Id = o.Id.SelectAll(), //Id是o任意一个属性
                //CustomName = cus.Name,
            })
           .FirstAsync();
        */


        var entity = await db.Queryable<SysLog>().SplitTable()
            .Where(it => it.Id == id).FirstAsync();
        if (entity == null)
        {
            throw Oops.Oh("未找到日志记录");
        }
        var result = entity.Adapt<ApiSysLogOut>();

        return result;
    }


    /// <summary>
    ///     分页查询
    /// </summary>
    /// <param name="searchQuery"></param>
    /// <returns></returns>
    [PgApiAction("分页查询")]
    [HttpPost]
    [OperationId(nameof(GetList))]
    public async Task<PagedList<ApiSysLogOut>> GetList(ApiSysLogQuery searchQuery)
    {
        /*
            var queryable = db.Queryable<SysLog, OrderItem, Custom>((o, i, c) => new JoinQueryInfos(
                   JoinType.Left, o.Id == i.OrderId, //左连接 左链接 左联
                   JoinType.Left, o.CustomId == c.Id
            ));
        */

        var queryable = db.Queryable<SysLog>();

        #region 筛选条件

        //开始日期
        if (searchQuery.StartDate.HasValue)
        {
            queryable = queryable.Where(o => o.CreationTime >= searchQuery.StartDate.Value);
        }
        //结束日期
        if (searchQuery.EndDate.HasValue)
        {
            queryable = queryable.Where(o => o.CreationTime <= searchQuery.EndDate.ToDayEndTime());
        }

        //日志类型
        if (searchQuery.LogType.HasValue)
        {
            queryable = queryable.Where(o => o.LogType == searchQuery.LogType.Value);
        }


        //是否成功
        if (searchQuery.IsSuccess.HasValue)
        {
            queryable = queryable.Where(o => o.IsSuccess == searchQuery.IsSuccess.Value);
        }


        //关键词
        if (!string.IsNullOrWhiteSpace(searchQuery.KeyWords))
        {
            var kw = searchQuery.KeyWords?.Trim()?.ToLower() ?? "";
            if (kw.IsValidLong())
            {
                var searchId = kw.ToLong();
                queryable = queryable.Where(o => o.Id == searchId || o.TableId == searchId || o.UserId == searchId ||
                o.Message.ToLower().Contains(kw) || o.Tag.ToLower().Contains(kw) ||
                o.Ip.ToLower().Contains(kw) || o.RequestUrl.ToLower().Contains(kw)
                );

            }
            else
            {
                queryable = queryable.Where(o => o.Message.ToLower().Contains(kw) ||
                o.Tag.ToLower().Contains(kw) || o.Ip.ToLower().Contains(kw) ||
                o.RequestUrl.ToLower().Contains(kw));
            }
        }

        #endregion

        queryable = queryable.OrderByDescending(o => o.Id);
        queryable = queryable.SplitTable();
        var pagelist = await queryable

            //这几个长字段不再返回
            //.IgnoreColumns(it => it.Message)
            //.IgnoreColumns(it => it.Exception)
            //.IgnoreColumns(it => it.LogContent)
            //.IgnoreColumns(it => it.WebFingerprint)
            //.IgnoreColumns(it => it.WebInfo)
            .Select(o => new ApiSysLogOut
            {
                Id = o.Id,
                CreationTime = o.CreationTime,
                CreatorUserId = o.CreatorUserId,
                CreatorUserName = o.CreatorUserName,
                LogTypeEnum = o.LogType,
                IsSuccess = o.IsSuccess,
                Ip = o.Ip,
                RequestUrl = o.RequestUrl,
                ElapsedTime = o.ElapsedTime,


            })

            .Mapper(src =>
            {
                src.LogType = src.LogTypeEnum.ToInt32();
            })
            .ToPagedListAsync(searchQuery.PageIndex, searchQuery.PageSize);


        //var pagelist= await pageResult.ToPagedListAsync<SysLog, ApiSysLogOut>(searchQuery.PageIndex, searchQuery.PageSize);

        return pagelist;
    }


    ///// <summary>
    ///// 设置状态
    ///// </summary>
    ///// <param name="id"></param>
    ///// <param name="state"></param>
    ///// <returns></returns>
    //[PgApiAction(name: "设置启用状态")]
    //[OperationId(nameof(SetIsEnable))]
    //public async Task<bool> SetIsEnable(long id, bool state)
    //{
    //    return await db.SetStateByIdAsync<SysLog>(id, state, "IsEnable");
    //}

    #region 冗余方法

    ///// <summary>
    ///// 查询所有
    ///// </summary>
    ///// <returns></returns>
    //[PgApiAction(name: "查询所有")]
    //[OperationId(nameof(GetAll))]
    //public async Task<List<ApiSysLogOut>> GetAll()
    //{
    //    return await db.GetListAsync<SysLog, ApiSysLogOut>();
    //}

    ///// <summary>
    ///// 获取下拉选项
    ///// </summary>
    ///// <returns></returns>
    //[PgApiAction(name: "获取下拉选项")]
    //[HttpPost]
    //[OperationId(nameof(GetSelectItems))]
    //public async Task<List<NKeyValue<long, string>>> GetSelectItems()
    //{
    //    var keyValues = await db.Queryable<SysLog>()
    //        .Select(o => new NKeyValue<long, string>() { Key = o.Id, Value = o.Name })
    //        .ToListAsync();
    //    return keyValues;
    //}

    #endregion
}